/*-------------------<-- Start of Description -->--------------------\ | Generate multi-normial distrubtion; | |-----------------------------------------| |--------------------------------------------------------------------| |-------------------------| | Arguments required: | | seed - the seed; default is the system time; | | n - the dimension of the output array; | | p - proportion table; | | m - the total size of the multi-normial distribution; | | var - the output var name or array names; | | Other Arguments: | | temp1 - internal temporary variable; | | temp2 - internal temporary variable; | | init - output the generated variates to an array; | | if 1, create an array using the name of the "var"as | | prefix; | | otherwise, the input variable "var" is an array, just | | use it to save the generated variates; | |---------------------------| |--------------------------------------------------------------------| |---------------------------------| | Example: | | data one; | | array _p(3) (0.25, 0.5, 0.25); | | %_ranmult(seed=1, var=x, n=3, p=_p, m=5); | | put x1-x3 _cdf1-_cdf2 seed; | | do i=1 to 100000; | | %_ranmult(seed=seed, var=x, m=5, n=3, p=_p, init=0); | | output; | | end; | | run; proc print data=one(obs=200); run; | | proc freq data=one; | | tables x1-x3 / list missing; | | run; | | Usage: %_ranmult(seed=%sysfunc(datetime(), 15.), var=, n=, p=, m=, | | temp1=_temp1, temp2=_temp2, init=1); | \----------------------------------*/ %macro _ranmult(seed=%sysfunc(datetime(), 15.), var=, n=, p=, m=, temp=_ranseed0_, temp1=_temp1, temp2=_temp2, init=1); /*--------------------------------------------\ | Copy Right: Duo Zhou; | | Created: 3-23-2001 9:12pm; | | Purpose: Random Multi-normial Generator; | \--------------------------------------------*/ %if (%quote(&seed) eq) or (%quote(&var) eq) or (%quote(&n) eq) or (%quote(&m) eq) or (%quote(&p) eq) %then %do; %if (%quote(&seed) eq) %then %do; %put ==> Error: This is not a valid seed!; %if (%length(&var)) %then %do; &var=.; %end; %end; %if (%quote(&var) eq) %then %do; %put ==> Error: This function will need a valid array to save the generated random; %put +++ variates!; %if (%length(&var)) %then %do; &var=.; %end; %end; %if (%quote(&n) eq) %then %do; %put ==> Error: I will save the generated random variates into the array "&var", so; %put +++ please provide array dimension !; %if (%length(&var)) %then %do; &var=.; %end; %end; %if (%quote(&p) eq) %then %do; %put ==> Error: I need a valid proportion or proportion array!; %if (%length(&var)) %then %do; &var=.; %end; %end; %if (%quote(&m) eq) %then %do; %put ==> Error: I need a total size for multi-normal distribution!; %if (%length(&var)) %then %do; &var=.; %end; %end; %goto finish; %end; %if (not %sysfunc(rxmatch(%sysfunc(rxparse(_|.|$a|$A|$w)),&seed))) %then %do; drop &temp; retain &temp &seed; %let seed=&temp; %end; %if &init %then %do; array &var(&n) &var.1 - &var.%left(&n); %end; do &temp1=1 to &n; &var(&temp1)=0; end; do &temp1=1 to &m; %_rantbl(seed=&seed, var=&temp2, n=&n, p=&p, init=&init); &var(&temp2)=&var(&temp2)+1; end; %finish: %mend _ranmult;